<?php

namespace App\Classes\Publish;

use App\Models\Task\Task;
use Illuminate\Support\Facades\DB;

class Publication
{
    /**
     * 筛选ids
     */
    public static function myfilter($model, $ids, $filters, $oparation)
    {
        try {
            $model = (new \ReflectionClass($model))->getName();
            // 处理总数
            $totalNum = count($ids);
            // 提示信息, 提示用户那些选项不满足什么条件
            $notices = [];
            // 过滤出每个条件不满足的ids
            foreach ($filters as $filter) {
                list($where, $failMessage) = $filter; // [[['async_result' , '<>', 0]], 'ID为以下媒资正在注入'],
                // 过滤之后的ids
                $filteredIds = $model::whereIn('id', $ids)->where($where)->pluck('id');

                $idsDiff = collect($ids)->diff($filteredIds);
                if ($idsDiff->first()) {
                    $notices[] = [$idsDiff, $failMessage];
                }
                // 每次过滤缩小ids范围
                $ids = $filteredIds;
                // 如果所有ids已经不满足条件了,则跳出循环,不进行后续筛选
                if (!$ids->first()) {
                    break;
                }
            }
            // 如果提示信息不为空,拼装提示信息
            $message = '';
            // 成功数量
            $successNum = $ids->count();
            // 失败数量
            $failNum = $totalNum - $successNum;
            $message = static::makeNoticeInfo($oparation, $totalNum, $successNum, $failNum, $notices);
            return [$ids, $message];
        } catch (\Exception $e) {
            dd($e->getMessage(), $e->getLine());
        }
    }

    /**
     * 组装错误提示信息;
     */
    public static function makeNoticeInfo($oparation, $totalNum, $successNum, $failNum, $notices)
    {
        $message = '';
        $message .= "{$oparation}总数 : ";
        $message .= $totalNum . '<br />';
        $message .= "{$oparation}成功数: ";
        $message .= $successNum . '<br />';
        $message .= "{$oparation}失败数: ";
        $message .= $failNum . '<br />';
        $errors = '';
        foreach ($notices as $notice) {
            list($failIds, $info) = $notice;
            // 如果当前错误类型的ids为空,则跳过这个错误
            if (empty($failIds) || !$failIds->first()) {
                continue;
            }
            $errors .= $info . $failIds->implode(', ') . '<br />';
        }
        $message .= $errors;
        // 如果错误信息为空, 注意这里拼接, div在前, $message在后, 顺序不能改
        if (empty($errors)) {
            $message = '<div style="word-wrap: break-word;" class="alert alert-success">' . $message;
        } else {
            // 如果错误信息不为空
            $message = '<div style="word-wrap: break-word;" class="alert alert-error">' . $message;
        }
        // 把最后一个多余的换行去掉
        $message = substr($message, 0, -6);
        $message .= '</div>';
        return $message;
    }

    /**
     * 统计需要处理的总数, 并返回那些数据不能处理的原因;
     */
    public static function getTotalNum($model, $filters, $oparation)
    {
        try {
            $model   = (new \ReflectionClass($model))->getName();
            $notices = [];
            // 全部的ids
            $ids      = $model::pluck('id');
            $allWhere = [];
            // 总共需要处理的总数
            $totalNum = $ids->count();
            foreach ($filters as $filter) {
                list($where, $failMessage) = $filter;
                $filteredIds               = $model::where($where)->pluck('id');
                // 每种条件不满足的ids
                $idsDiff = $ids->diff($filteredIds);
                if ($idsDiff->first()) {
                    $notices[] = [$idsDiff, $failMessage];
                }
                $allWhere = array_merge($allWhere, $where);
            }
            // 清除这三个大数组占用的内存
            $ids         = null;
            $filteredIds = null;
            $idsDiff     = null;
            // 符合全部条件的总数
            $total_num = $model::where($allWhere)->count();
            // 如果提示信息不为空,拼装提示信息
            $message = '';
            // 成功数量
            $successNum = $total_num;
            // 失败数量
            $failNum = $totalNum - $successNum;
            $message = static::makeNoticeInfo($oparation, $totalNum, $successNum, $failNum, $notices);
            return [$total_num, $message];
        } catch (\Exception $e) {
            dd($e->getMessage());
        }
    }

    /**
     * 统计需要处理的任务ids;
     */
    public static function getTotalIds($model, $filter)
    {
        try {
            $model = (new \ReflectionClass($model))->getName();
            return $model::where($filter)->select('id')->get();
        } catch (\Exception $e) {
            dd($e->getMessage());
        }
    }

    /**
     * 统计某个字段在给定集合中,需要处理的任务记录数
     */
    public static function getTotal($model, $field, $filter)
    {
        try {
            $model = (new \ReflectionClass($model))->getName();
            return $model::whereIn($field, $filter)->count();
        } catch (\Exception $e) {
            dd($e->getMessage());
        }
    }

    /**
     * 更新上线,下线,发布,销售状态
     */
    public static function updateMany($model, $ids, $data)
    {
        try {
            $model = (new \ReflectionClass($model))->getName();
            return $model::whereIn('id', $ids)->update($data);
        } catch (\Exception $e) {
            dd($e->getMessage());
        }
    }

    /**
     * 更新上线,下线,发布,销售状态
     */
    public static function updateOne($model, $id, $data)
    {
        try {
            $model = (new \ReflectionClass($model))->getName();
            return $model::where('id', $id)->update($data);
        } catch (\Exception $e) {
            dd($e->getMessage());
        }
    }

    /**
     * 查询进度,静态供其他类调用
     */
    public static function progress($taskid)
    {
        $data = Task::where('id', $taskid)->first();
        if ($data->total_num === 0) {
            return response()->json(['percent' => '0%']);
        }
        if ($data->total_num === -1) {
            return response()->json(['percent' => '100%']);
        }
        return response()->json(['percent' => ceil($data->done_num * 100 / $data->total_num) . '%']);
    }

    /**
     * 获取需要插入的接口的数据
     */
    public static function getDatas($field, $ids)
    {
        try {
            $model = (new \ReflectionClass($model))->getName();
            return $model::whereIn($field, $ids)->get();
        } catch (\Exception $e) {
            dd($e->getMessage());
        }
    }

    /**
     * 将数据插入到接口库中
     */
    public static function insertApi($model, $data)
    {
        try {
            return DB::connection('interface')->table($model)->insert($data);
        } catch (\Exception $e) {
            dd($e->getMessage());
        }
    }

    /**
     * 下线删除接口库中对应媒资内容
     */
    public static function deleteApi($model, $field, $ids)
    {
        try {
            return DB::connection('interface')->table($model)->whereIn($field, $ids)->delete();
        } catch (\Exception $e) {
            dd($e->getMessage());
        }

    }

    /**
     * 获取一个任务id
     */
    public static function insertTasks($data)
    {
        try {
            return Task::insertGetId($data);
        } catch (\Exception $e) {
            dd($e->getMessage());
        }
    }

    /**
     * 对数据进行分块操作
     */
    public static function chunk($model, $job, $status, $chunk_num, $option)
    {
        try {
            $taskid = $job->taskid;
            $model  = (new \ReflectionClass($model))->getName();
            $job    = (new \ReflectionClass($job))->getName();
            $model::where($status)->select('id')->chunk($chunk_num, function ($ids) use ($job, $option, $taskid) {
                if ($ids->first()) {
                    dispatch(new $job($option, $ids->pluck('id'), $taskid));
                }
            });
        } catch (\Exception $e) {
            dd($e->getMessage());
        }
    }

    /**
     * 获取表中某个字段信息,如user_id
     */
    public static function getField($model, $id, $field)
    {
        try {
            $model = (new \ReflectionClass($model))->getName();
            return $model::where('id', $id)->value($field);
        } catch (\Exception $e) {
            dd($e->getMessage());
        }
    }

    /**
     * 状态过滤功能
     */
    public static function statusFilter($status, $published, &$grid)
    {
        // 状态过滤
        $fields = ['all', 'on', 'off'];
        if (in_array($status, $fields) && in_array($published, $fields)) {
            switch ($status) {
                case 'all':
                    switch ($published) {
                        case 'all':
                            break;
                        case 'on':
                            $grid->model()->where(['publish_status' => 1])->orWhere(['publish_down_status' => 1]);
                            break;
                        case 'off':
                            $grid->model()->where(['online_status' => 1, 'publish_status' => 0])
                                ->orWhere(['online_status' => 0, 'publish_down_status' => 0]);
                            break;
                    }
                    break;
                case 'on':
                    switch ($published) {
                        case 'all':
                            $grid->model()->where(['online_status' => 1]);
                            break;
                        case 'on':
                            $grid->model()->where(['online_status' => 1, 'publish_status' => 1]);
                            break;
                        case 'off':
                            $grid->model()->where(['online_status' => 1, 'publish_status' => 0]);
                            break;
                    }
                    break;
                case 'off':
                    switch ($published) {
                        case 'all':
                            $grid->model()->where(['online_status' => 0]);
                            break;
                        case 'on':
                            $grid->model()->where(['online_status' => 0, 'publish_down_status' => 1]);
                            break;
                        case 'off':
                            $grid->model()->where(['online_status' => 0, 'publish_down_status' => 0]);
                            break;
                    }
                    break;
            }
        }
    }

}
